#pragma once

#include "XamlReader.h"
#include "XamlBinaryMetadataReader.h"
#include "XamlNode.h"
#include "XamlPullParser.h"

class XamlBinaryFormatReader :
	public XamlReader
{

private: 
	XamlBinaryFormatReader(const xshared_ptr<XamlSchemaContext> & spXamlSchemaContext, const xshared_ptr<XamlBinaryMetadataReader> & spXamlBinaryMetadataReader, struct IPALStream * pNodeStreamStream);
	HRESULT Initialize(struct IPALStream * pNodeStreamStream);
public: 
	static HRESULT Create(xshared_ptr<XamlSchemaContext> spXamlSchemaContext, xshared_ptr<XamlBinaryMetadataReader> spXamlBinaryMetadataReader, struct IPALStream * pNodeStreamStream, xshared_ptr<XamlBinaryFormatReader> & spXamlBinaryFormatReader);
	virtual ~XamlBinaryFormatReader();
	virtual HRESULT Read();
	virtual const XamlNode & CurrentNode();
	virtual HRESULT GetSchemaContext(xshared_ptr<XamlSchemaContext> & outSchemaContext);
private: 
	HRESULT ReadNodeType(enum XamlNode::XamlNodeType & nodeType);
	HRESULT ReadLineInfo();
	HRESULT ReadAddNamespaceNode();
	HRESULT ReadStartObjectNode();
	HRESULT ReadEndObjectNode();
	HRESULT ReadStartMemberNode();
	HRESULT ReadEndMemberNode();
	HRESULT ReadEndOfAttributesNode();
	HRESULT ReadEndOfStreamNode();
	HRESULT ReadTextValueNode();
	HRESULT ReadValueNode();
	HRESULT ReadFromNodeStreamBuffer(XUINT8 * pbTarget, XUINT32 cbRead);
	HRESULT ReadPersistedXamlNode(struct PersistedXamlNode & targetNode);
	HRESULT ReadPersistedString(xshared_ptr<CXString> & targetString);

private: 
	xshared_ptr<XamlPullParser> m_spXamlPullParser;
	XamlNode m_currentXamlNode;
	XamlLineInfo m_currentLineInfo;
	xshared_ptr<XamlSchemaContext> m_spXamlSchemaContext;
	xshared_ptr<XamlBinaryMetadataReader> m_spXamlBinaryMetadataReader; 
	xref_ptr<IPALStream> m_spNodeStreamStream; 
	XUINT8 * m_pbNodeStream;
	XUINT32 m_cbNodeStream;
	XUINT32 m_cbNodeStreamRead;
};